/*===============================================
Copyright (c): Technology Co.,Ltd. ALL rights reserved. 
                                                                 
  Create by:LIN
      Email:
       Date:
   Filename:
Description:
    Version:
Last Change:
                                                                 
=======================================*/
                                                                 
`ifndef MAC_SEQ_SV
`define MAC_SEQ_SV

`include "mac_seq_item.sv"

class mac_base_seq extends uvm_sequence #(mac_seq_item);

	rand int port_num = -1;
	rand int ntrans = 10;
	rand int data_size = -1;
	rand int crc_error;
	rand int dv_error;
	rand bit [47:0] destiny_mac_addr;
	rand bit [47:0] source_mac_addr;
	static rand bit [47:0] rand_mac_addr[PORT_NUM][5];
	static bit is_init = 0;


	constraint cstr {
		soft port_num == -1;
		soft data_size == -1;
        	soft ntrans == 10;
		soft dv_error dist {0 :/ 100, 1 :/ 0};
		soft crc_error dist {0 :/ 90, 1 :/ 10};
		dv_error == 1 -> crc_error == 0;
	};

	`uvm_object_utils_begin(mac_base_seq)
        `uvm_field_int(port_num, UVM_ALL_ON)
		`uvm_field_int(data_size, UVM_ALL_ON)
        `uvm_field_int(ntrans, UVM_ALL_ON)
		`uvm_field_int(crc_error, UVM_ALL_ON)
		`uvm_field_int(destiny_mac_addr, UVM_ALL_ON)
		`uvm_field_int(source_mac_addr, UVM_ALL_ON)
	`uvm_object_utils_end

	`uvm_declare_p_sequencer(mac_sequencer)

	function new(string name = "mac_base_seq");
		super.new(name);
		if (!is_init) begin
			foreach(rand_mac_addr[i]) begin
				foreach (rand_mac_addr[i][j]) begin
					rand_mac_addr[i][j] = $urandom_range(48'h1, 48'hffffffffffff);
				end
			end
			is_init = 1;
		end
		rand_mac_addr.rand_mode(0);
		`uvm_info("TRACE", $sformatf("%m"), UVM_HIGH);
		
	endfunction

	function void pre_randomize();

	endfunction

	task body();
		repeat(ntrans) begin
			mac_seq_item req, rsp;
			`uvm_do_with(req, {local::port_num >= 0 -> port_num == local::port_num;
								local::crc_error >= 0 -> crc_error == local::crc_error;
								local::dv_error >= 0 -> dv_error == local::dv_error;
								local::data_size > 0 -> pload.size() == local::data_size;
								local::destiny_mac_addr != local::source_mac_addr;
								local::destiny_mac_addr > 0 -> local::destiny_mac_addr == destiny_mac_addr;
								local::source_mac_addr > 0 -> local::source_mac_addr == source_mac_addr;})
			`uvm_info(get_type_name(), {"req item\n", req.sprint()}, UVM_HIGH)
		end
	endtask

endclass



class mac_multi_port_transer_smoke_seq extends uvm_sequence;

	mac_base_seq mac_seq;
	
	`uvm_object_utils(mac_multi_port_transer_smoke_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "mac_multi_port_transer_smoke_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_LOW)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_LOW)
	endtask

	task do_data();
		fork
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 50; port_num == 0;
			data_size inside {[50:100]}; crc_error == 0;dv_error == 0;})
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 50; port_num == 1;
			data_size inside {[100:200]}; crc_error == 0;dv_error == 0;})
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 50; port_num == 2;
			data_size inside {[200:300]}; crc_error == 0;dv_error == 0;})
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 50; port_num == 3;
			data_size inside {[300:400]}; crc_error == 0;dv_error == 0;})
		join
		#10us;
	endtask

endclass

class mac_single_port_polling_smoke_seq extends uvm_sequence;

	mac_base_seq mac_seq;
	
	`uvm_object_utils(mac_single_port_polling_smoke_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "mac_single_port_polling_smoke_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_HIGH)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_HIGH)
	endtask

	task do_data();
		
		for (int i = 0; i < 30; i++) begin
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[i%4], {ntrans == 1; port_num == i%4;
			data_size inside {[100:200]}; crc_error == 0; dv_error == 0;})
			#10us;
		end
	endtask

endclass

class mac_crc_error_smoke_seq extends uvm_sequence;

	mac_base_seq mac_seq;
	
	`uvm_object_utils(mac_crc_error_smoke_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "mac_crc_error_smoke_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_HIGH)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_HIGH)
	endtask

	task do_data();
		fork
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 50; 
							port_num == 0; data_size inside {[50:100]};}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 50; 
							port_num == 1; data_size inside {[50:100]};}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 50; 
							port_num == 2; data_size inside {[50:100]};}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 50; 
							port_num == 3; data_size inside {[50:100]};}) 
		join
	endtask

endclass

class mac_lut_study_smoke_seq extends uvm_sequence;

	mac_base_seq mac_seq;
	
	`uvm_object_utils(mac_lut_study_smoke_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "mac_lut_study_smoke_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_HIGH)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_HIGH)
	endtask

	task do_data();
		for (int i = 0; i < 5; i++) begin
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; 
							port_num == 0; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr inside {rand_mac_addr[1][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
							source_mac_addr inside {rand_mac_addr[0][i]};
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; 
							port_num == 1; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
							source_mac_addr inside {rand_mac_addr[1][i]};
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; 
							port_num == 2; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[3][i]};
							source_mac_addr inside {rand_mac_addr[2][i]};
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 1; 
							port_num == 3; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[2][i]};
							source_mac_addr inside {rand_mac_addr[3][i]};
							destiny_mac_addr != source_mac_addr;}) 
			fork
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 10; 
								port_num == 0; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
								destiny_mac_addr inside {rand_mac_addr[1][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
								source_mac_addr inside {rand_mac_addr[0][i]};
								destiny_mac_addr != source_mac_addr;}) 
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 10; 
								port_num == 1; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
								destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
								source_mac_addr inside {rand_mac_addr[1][i]};
								destiny_mac_addr != source_mac_addr;}) 
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 10; 
								port_num == 2; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
								destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[3][i]};
								source_mac_addr inside {rand_mac_addr[2][i]};
								destiny_mac_addr != source_mac_addr;}) 
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 10; 
								port_num == 3; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
								destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[2][i]};
								source_mac_addr inside {rand_mac_addr[3][i]};
								destiny_mac_addr != source_mac_addr;}) 
			join
		end
	endtask

endclass

class switch_random_test_seq extends uvm_sequence;

	mac_base_seq mac_seq;
		
	`uvm_object_utils(switch_random_test_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "mac_lut_study_smoke_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_HIGH)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_HIGH)
	endtask

	task do_data();

		for (int i = 0; i < 5; i++) begin
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; port_num == 0; dv_error == 0;
			data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[1][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
			source_mac_addr inside {rand_mac_addr[0][i]};destiny_mac_addr != source_mac_addr;})
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; port_num == 1; dv_error == 0;
			data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
			source_mac_addr inside {rand_mac_addr[1][i]};destiny_mac_addr != source_mac_addr;})
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; port_num == 2; dv_error == 0;
			data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[3][i]};
			source_mac_addr inside {rand_mac_addr[2][i]};destiny_mac_addr != source_mac_addr;})
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 1; port_num == 3; dv_error == 0;
			data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[2][i]};
			source_mac_addr inside {rand_mac_addr[3][i]};destiny_mac_addr != source_mac_addr;})

			fork
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 10; port_num == 0; dv_error == 0;
				data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[1][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
				source_mac_addr inside {rand_mac_addr[0][i]};destiny_mac_addr != source_mac_addr;})
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 10; port_num == 1; dv_error == 0;
				data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[2][i], rand_mac_addr[3][i]};
				source_mac_addr inside {rand_mac_addr[1][i]};destiny_mac_addr != source_mac_addr;})
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 10; port_num == 2; dv_error == 0;
				data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[3][i]};
				source_mac_addr inside {rand_mac_addr[2][i]};destiny_mac_addr != source_mac_addr;})
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 10; port_num == 3; dv_error == 0;
				data_size inside {[50:1500]}; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][i], rand_mac_addr[1][i], rand_mac_addr[2][i]};
				source_mac_addr inside {rand_mac_addr[3][i]};destiny_mac_addr != source_mac_addr;})
			join
		end
	endtask

endclass

class cover_case_seq extends uvm_sequence;

	mac_base_seq mac_seq;
	
	`uvm_object_utils(cover_case_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "cover_case_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_HIGH)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_HIGH)
	endtask

	task do_data();

				
		`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; 
						port_num == 0; data_size == 1510; crc_error == 0; dv_error == 0;
						destiny_mac_addr != source_mac_addr;}) 
		`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; 
						port_num == 1; data_size == 800; crc_error == 0; dv_error == 0;
						destiny_mac_addr != source_mac_addr;}) 
		`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; 
						port_num == 2; data_size == 800; crc_error == 0; dv_error == 0;
						destiny_mac_addr != source_mac_addr;}) 
		`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 50; 
						port_num == 3; data_size == 46; crc_error == 0; dv_error == 0;
						destiny_mac_addr != source_mac_addr;}) 


		for (int i = 0; i < 5; i++) begin
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; 
							port_num == 0; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr == 48'hffffffffffff;
							source_mac_addr inside {rand_mac_addr[0][i]};
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; 
							port_num == 1; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr == 48'hffffffffffff;
							source_mac_addr inside {rand_mac_addr[1][i]};
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; 
							port_num == 2; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr == 48'hffffffffffff;
							source_mac_addr inside {rand_mac_addr[2][i]};
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 1; 
							port_num == 3; data_size inside {[50:100]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr == 48'hffffffffffff;
							source_mac_addr inside {rand_mac_addr[3][i]};
							destiny_mac_addr != source_mac_addr;}) 
		end

		for (int i = 0; i < 5; i++) begin
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; 
							port_num == 0; data_size inside {[1400:1600]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; 
							port_num == 1; data_size inside {[1400:1600]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; 
							port_num == 2; data_size inside {[1400:1600]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 1; 
							port_num == 3; data_size inside {[1400:1600]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
		end
		for (int i = 0; i < 5; i++) begin
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; 
							port_num == 0; data_size inside {[10:80]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; 
							port_num == 1; data_size inside {[10:80]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; 
							port_num == 2; data_size inside {[10:80]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
			`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 1; 
							port_num == 3; data_size inside {[10:80]}; crc_error == 0; dv_error == 0;
							destiny_mac_addr != source_mac_addr;}) 
		end

	endtask

endclass


class perf_test_seq extends uvm_sequence;
	`define PERF_TEST_DATA_LEN	64
	mac_base_seq mac_seq;
	
	`uvm_object_utils(perf_test_seq)
	`uvm_declare_p_sequencer(switch_virtual_sequencer)

	function new (string name = "perf_test_seq");
		super.new(name);
	endfunction

	virtual task body();
	
		`uvm_info(get_type_name(), "\n=====================Started=====================", UVM_HIGH)

		this.do_data();

		`uvm_info(get_type_name(), "\n=====================Finished=====================", UVM_HIGH)
	endtask

	task do_data();
		//	`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 1; port_num == 0; dv_error == 0;
		//	data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[1][0], rand_mac_addr[2][0], rand_mac_addr[3][0]};
		//	source_mac_addr inside {rand_mac_addr[0][0]};destiny_mac_addr != source_mac_addr;})
		//	`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 1; port_num == 1; dv_error == 0;
		//	data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][0], rand_mac_addr[2][0], rand_mac_addr[3][0]};
		//	source_mac_addr inside {rand_mac_addr[1][0]};destiny_mac_addr != source_mac_addr;})
		//	`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 1; port_num == 2; dv_error == 0;
		//	data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][0], rand_mac_addr[1][0], rand_mac_addr[3][0]};
		//	source_mac_addr inside {rand_mac_addr[2][0]};destiny_mac_addr != source_mac_addr;})
		//	`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 1; port_num == 3; dv_error == 0;
		//	data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr inside {rand_mac_addr[0][0], rand_mac_addr[1][0], rand_mac_addr[2][0]};
		//	source_mac_addr inside {rand_mac_addr[3][0]};destiny_mac_addr != source_mac_addr;})

			fork
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[0], {ntrans == 100; port_num == 0; dv_error == 0;
				data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr != source_mac_addr;})
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[1], {ntrans == 100; port_num == 1; dv_error == 0;
				data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr != source_mac_addr;})
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[2], {ntrans == 100; port_num == 2; dv_error == 0;
				data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr != source_mac_addr;})
				`uvm_do_on_with(mac_seq, p_sequencer.mac_mii_sqrs[3], {ntrans == 100; port_num == 3; dv_error == 0;
				data_size == `PERF_TEST_DATA_LEN; crc_error == 0; destiny_mac_addr != source_mac_addr;})
			join
				

	endtask

endclass





`endif
